﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using ZealousTTS.Domain;
using ZealousTTS.Web.ViewModels;
using ZealousTTS.Common.Extensions;
using AutoMapper;
using System.Text;
using System.Configuration;
using ZealousTTS.Common.DB;

namespace ZealousTTS.Web.Utility
{
    public class BootStrapper
    {
        /// <summary>
        /// Configures the AutoMapper with appropriate Domain DataModel and UI ViewModel types
        /// </summary>
        public static void ConfigureTypeMappings()
        {
            ///Mapper needed for auto converters
            DateTimeToStringConverter dateToString = new DateTimeToStringConverter();
            StringToDateTimeConverter stringToDateTime = new StringToDateTimeConverter();
            StringToNullableDateTimeConverter stringToNullableDateTimeConverter = new StringToNullableDateTimeConverter();

            Mapper.CreateMap<String, DateTime>().ConvertUsing(stringToDateTime);
            Mapper.CreateMap<String, DateTime?>().ConvertUsing(stringToNullableDateTimeConverter);
            Mapper.CreateMap<DateTime, String>().ConvertUsing(dateToString);

            StringToBoolean stringToBoolean = new StringToBoolean();
            BooleanToString booleanToString = new BooleanToString();
            Mapper.CreateMap<String, bool>().ConvertUsing(stringToBoolean);
            Mapper.CreateMap<bool, String>().ConvertUsing(booleanToString);

            IntToNullableInt intToNullableInt = new IntToNullableInt();
            Mapper.CreateMap<int, int?>().ConvertUsing(intToNullableInt);

            ///AutoMapper configuration for IndustryType Entity
            //Mapper.CreateMap<IndustryType, IndustryTypeViewModel>();
            //Mapper.CreateMap<IndustryTypeViewModel, IndustryType>();

            ///User Mapper
            Mapper.CreateMap<User, UserViewModel>();
            Mapper.CreateMap<UserViewModel, User>();

            ///User Mapper
            Mapper.CreateMap<Group, GroupViewModel>();
            Mapper.CreateMap<GroupViewModel, Group>();

            ///Project Mapper
            Mapper.CreateMap<Project, ProjectViewModel>();
            Mapper.CreateMap<ProjectViewModel, Project>();


            //Prioritiy Mapper
            Mapper.CreateMap<Prioritiy, PrioritiyViewModel>();
            Mapper.CreateMap<PrioritiyViewModel, Prioritiy>();

            //Status Mapper
            Mapper.CreateMap<Status, StatusViewModel>();
            Mapper.CreateMap<StatusViewModel, Status>();

            //Task Mapper
            Mapper.CreateMap<Task, TaskViewModel>();
            Mapper.CreateMap<TaskViewModel, Task>();

            /////Company Mapper
            //Mapper.CreateMap<Company, CompanyViewModel>();
            //Mapper.CreateMap<CompanyViewModel, Company>();

            /////Contact Mapper
            //Mapper.CreateMap<Contact, ContactViewModel>();
            //Mapper.CreateMap<ContactViewModel, Contact>();

            /////Content Mapper
            //Mapper.CreateMap<Content, ContentViewModel>();
            //Mapper.CreateMap<ContentViewModel, Content>();

            ////Job Mapper
            //Mapper.CreateMap<Job, JobViewModel>();
            //Mapper.CreateMap<JobViewModel, Job>();

            ////Skill Mapper
            //Mapper.CreateMap<Skill, SkillViewModel>();
            //Mapper.CreateMap<SkillViewModel, Skill>();

            ////Education Mapper
            //Mapper.CreateMap<Education, EducationViewModel>();
            //Mapper.CreateMap<EducationViewModel, Education>();

            ////Coverletter Mapper
            //Mapper.CreateMap<CoverLetter, CoverLetterViewModel>();
            //Mapper.CreateMap<CoverLetterViewModel, CoverLetter>();

            ////Address Mapper
            //Mapper.CreateMap<Address, AddressViewModel>();
            //Mapper.CreateMap<AddressViewModel, Address>();

            #region LGL Mappings
            ///LGL Mappings
            //Mapper.CreateMap<ViewModels.LGL.Category.Category, ViewModels.LGL.Product.Product>();
            #endregion LGL Mapping
        }

        /// <summary>
        /// Caches the User Groups in the Application Context
        /// </summary>
        public static void SetUserRoles()
        {
            ZealousTTSEntities context = new ZealousTTSEntities();
            var groups = context.Groups;
            StringBuilder sb = new StringBuilder();
            foreach (Group group in groups)
            {
                if (sb.Length == 0)
                    sb.Append(group.Name);
                else
                    sb.AppendFormat(",{0}", group.Name);
            }
            ZealousTTS.Common.Authentication.AppAuthorizeAttribute.UserRoles = sb.ToString();
        }

        public static void PrepareDomainUtility()
        {
            String connectionString = ConfigurationManager.ConnectionStrings["ZealousTTSEntities"].ConnectionString;
            connectionString = connectionString.Substring(connectionString.IndexOf("\"")).Replace("\"", String.Empty);
            ZealousTTS.Domain.UtilityDAO.ConnectionString = connectionString;
        }
    }

    #region  Value Converters
    /// <summary>
    /// Used to Convert String DateTime to DateTime Object
    /// </summary>
    public class StringToDateTimeConverter : ITypeConverter<String, DateTime>
    {       
        public DateTime Convert(ResolutionContext context)
        {
            if (context.SourceValue == null)
                return DateTime.MinValue;
            String sourceValue = ((String)context.SourceValue);
            return sourceValue.IsEmpty() ? DateTime.MinValue : sourceValue.ToDateTime(ConfigReader.CSharpCalendarDateFormat);
        }
    }
    public class StringToNullableDateTimeConverter : ITypeConverter<String, DateTime?>
    {
        public DateTime? Convert(ResolutionContext context)
        {
            if (context.SourceValue == null)
                return null; //DateTime.MinValue;
            String sourceValue = ((String)context.SourceValue);
            if (sourceValue.IsEmpty())
                return null;
            return sourceValue.ToDateTime(ConfigReader.CSharpCalendarDateFormat);
            //return sourceValue.IsEmpty() ? null : sourceValue.ToDateTime(ConfigReader.CSharpCalendarDateFormat);
        }
    }

    /// <summary>
    /// Used to Convert DateTime object to String, that will be shown to the UI for edit
    /// </summary>
    public class DateTimeToStringConverter : ITypeConverter<DateTime, String>
    {
        public String Convert(ResolutionContext context)
        {
            if (context.SourceValue == null)
                return String.Empty;

            DateTime sourceValue = ((DateTime)context.SourceValue);
            return sourceValue == DateTime.MinValue ? String.Empty : sourceValue.ToString(ConfigReader.CSharpCalendarDateFormat);
        }
    }

    public class StringToBoolean : ITypeConverter<String, Boolean>
    {
        public bool Convert(ResolutionContext context)
        {
            if (context.SourceValue == null)
                return false;

            return NullHandler.GetString(context.SourceValue).ToBoolean();            
        }
    }
    public class BooleanToString : ITypeConverter<bool, String>
    {
        public string Convert(ResolutionContext context)
        {
            if (context.SourceValue == null)
                return String.Empty;

            return context.SourceValue.ToString();
        }
    }

    public class IntToNullableInt : ITypeConverter<int, int?>
    {
        public int? Convert(ResolutionContext context)
        {
            if (context.SourceValue == null)
                return null;
            
            if (NullHandler.GetInt(context.SourceValue) == 0)
                return null;

            return NullHandler.GetInt(context.SourceValue);
        }
    }

    #endregion Value Converters
}